home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* */
- /* Application: Offscreen Animation */
- /* */
- /* Description: This sample shows how to use the QuickDraw™ GX */
- /* offscreenlibrary to perform simple animation. */
- /* */
- /* Files: Offscreen Animation.π */
- /* Offscreen Animation.c */
- /* */
- /* Programmer: Edgar Lee */
- /* Organization: Apple Computer, Inc. */
- /* Department: Developer Technical Support, DTS */
- /* Language: C (Think C version 6.0) */
- /* Recompiled: Think C version 7.0.6 */
- /* Date Created: 12-13-92 */
- /* */
- /* Change History: 9/93: Updated to run with QuickDraw GX ß2 "GXified" */
- /* interface files - PLA */
- /* */
- /* 4/96: Updated #includes to support changed GX Library */
- /* names. */
- /* Recompiled by unchecking Compiler Option - */
- /* "Generate 68881 instructions", this allows it */
- /* to run on CPUs without a FPU. */
- /* Changed fixed to Fixed. */
- /* Added the copyright info. - BOB */
- /* */
- /* */
- /* ©1992 - 1996 Apple Computer Inc. All Rights reserved. */
- /* */
- /****************************************************************************/
-
- #include <Desk.h>
- #include <Events.h>
- #include <Fonts.h>
- #include <Windows.h>
- #include <Memory.h>
- #include <ToolUtils.h>
- #include <OSEvents.h>
- #include <Quickdraw.h>
-
- #include <GXEnvironment.h>
- #include <GXGraphics.h>
- #include "GraphicsLibraries.h"
- #include <GXErrors.h>
- #include "QDLibrary.h"
- #include "OffscreenLibrary.h"
-
- /*-----------------------------------------------------------------------------------*/
-
- /*************************/
- /* Constant Declarations */
- /*************************/
-
- #define kWinWidth 400 /* The window width. */
- #define kWinHeight 300 /* The window height. */
-
- #define kWinLeft (((qd.screenBits.bounds.right - qd.screenBits.bounds.left) - kWinWidth) / 2)
- #define kWinTop (((qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) - kWinHeight) / 2)
-
- #define kMaxObjects 100 /* Total moving objects in offscreen. */
-
- typedef struct {
- gxShape shape;
- int xdelta;
- int ydelta;
- } movingObjectType;
-
- /*******************************/
- /* Global Variable Definitions */
- /*******************************/
-
- WindowPtr gWindow; /* The cgrafport. */
- offscreen gOffscreen;
-
- gxShape gTheBackground; /* The offscreen background. */
- movingObjectType gMovingObject[kMaxObjects]; /* The moving offscreen objects. */
-
- void initMac(void); /* Initializes the mac. */
- void createWindow(void); /* Initializes the window's cgrafport. */
- void doEventLoop(void); /* Handles events. */
-
- void createOffscreen(void); /* Creates a GX offscreen. */
- void initializeShapes(void); /* Initializes the shapes used in the offscreen. */
- void updateOffscreen(void); /* Updates the position of the moving shapes. */
- void drawOffscreen(void); /* Draw the offscreen to the window. */
- void disposeOffscreen(void); /* Disposes the memory used for the offscreen. */
-
- int randomInteger(int min, int max); /* Returns a random integer. */
- int randomSignInteger(int start,int end); /* Returns a variation of randomInteger. */
- int absInteger(int num); /* Returns the absolute value. */
- void getRandomColor(long *r,long *g,long *b); /* Returns a random old QD gxColor. */
-
- /*-----------------------------------------------------------------------------------*/
-
- main()
- {
- gxGraphicsClient client;
-
- initMac();
-
- client = GXNewGraphicsClient( nil, 2000L * 1024, 0L );
-
- createWindow();
-
- createOffscreen();
- initializeShapes();
-
- doEventLoop();
-
- disposeOffscreen();
- GXDisposeGraphicsClient( client );
- }
-
- /*-----------------------------------------------------------------------------------*/
-
- void initMac()
- {
- MaxApplZone();
- MoreMasters (); MoreMasters (); MoreMasters (); MoreMasters ();
-
- InitGraf( &qd.thePort );
- InitFonts();
- InitWindows();
- /***
- InitMenus();
- TEInit();
- InitDialogs( nil );***/
- InitCursor();
- FlushEvents( 0, everyEvent );
-
- qd.randSeed = TickCount();
- }
-
- /*-----------------------------------------------------------------------------------*/
-
- void createWindow()
- {
- Rect rect;
-
- SetRect( &rect, kWinLeft, kWinTop, kWinLeft + kWinWidth, kWinTop + kWinHeight );
- gWindow = NewCWindow( 0L, &rect, "\pOffscreen Animation", true, documentProc,
- (WindowPtr)-1L, true, 0L );
- SetPort( gWindow );
- SetDefaultViewPort( GXNewWindowViewPort( gWindow ) );
- }
-
- /*-----------------------------------------------------------------------------------*/
-
- void initializeShapes()
- {
- int i;
- int radius, minRadius, maxRadius;
- long red, green, blue;
- float brightnessFactor;
- gxRectangle bgRectData = { ff( 0 ), ff( 0 ), ff( kWinWidth ), ff( kWinHeight ) };
- gxRectangle objectRectData;
-
- /******************************************************/
- /* Initialize the background shape for the offscreen. */
- /******************************************************/
-
- gTheBackground = GXNewRectangle( &bgRectData );
- GXSetShapeTransform( gTheBackground, gOffscreen.xform );
- SetShapeRGB( gTheBackground, 0, 0, 0 );
-
- /**************************************************/
- /* Initialize the moving shapes in the offscreen. */
- /**************************************************/
-
- for (i = 0; i < kMaxObjects; i++)
- {
- /***************************************/
- /* Define the shape's movement offset. */
- /***************************************/
-
- if (i < (2 * kMaxObjects) / 3)
- {
- minRadius = 1;
- maxRadius = 3;
- }
- else if (i >= (2 * kMaxObjects) / 3 && i < (7 * kMaxObjects) / 8)
- {
- minRadius = 4;
- maxRadius = 6;
- }
- else if (i >= (7 * kMaxObjects) / 8 && i < kMaxObjects)
- {
- minRadius = 7;
- maxRadius = 10;
- }
-
- gMovingObject[i].xdelta = randomSignInteger( minRadius, maxRadius );
- gMovingObject[i].ydelta = randomSignInteger( minRadius, maxRadius );
-
- /****************************/
- /* Define the shape's size. */
- /****************************/
-
- if (absInteger( gMovingObject[i].xdelta ) >= absInteger( gMovingObject[i].ydelta ))
- radius = absInteger( gMovingObject[i].xdelta );
- else
- radius = absInteger( gMovingObject[i].ydelta );
-
- objectRectData.left = ff( randomInteger( 1, kWinWidth ) );
- objectRectData.top = ff( randomInteger( 1, kWinHeight ) );
- objectRectData.right = objectRectData.left + ff( radius );
- objectRectData.bottom = objectRectData.top + ff( radius );
-
- gMovingObject[i].shape = GXNewRectangle( &objectRectData );
- GXSetShapeTransform( gMovingObject[i].shape, gOffscreen.xform );
-
- /*****************************/
- /* Define the shape's gxColor. */
- /*****************************/
-
- brightnessFactor = (float)radius / 10.;
- getRandomColor( &red, &green, &blue );
-
- SetShapeRGB( gMovingObject[i].shape, red * brightnessFactor,
- green * brightnessFactor, blue * brightnessFactor );
- }
- }
-
- /*-----------------------------------------------------------------------------------*/
-
- void createOffscreen()
- {
- Rect rect;
- gxBitmap bm;
- gxShape offscreenShape;
-
- rect = (*gWindow).portRect;
-
- bm.width = rect.right - rect.left;
- bm.height = rect.bottom - rect.top;
- bm.pixelSize = 8;
- bm.rowBytes = 0;
- bm.space = gxIndexedSpace;
- bm.set = CTableToColorSet( GetCTable( 8 ) );
- bm.profile = nil;
- bm.image = nil;
-
- offscreenShape = GXNewBitmap( &bm, nil );
- CreateOffscreen( &gOffscreen, offscreenShape );
- }
-
- /*-----------------------------------------------------------------------------------*/
-
- void updateOffscreen()
- {
- int i;
- Fixed xpos, ypos;
- Fixed xdelta, ydelta;
- gxRectangle bounds;
- gxViewPort savedViewPort;
-
- /**********************************************************/
- /* Draw the background shape to erase the previous image. */
- /**********************************************************/
-
- GXDrawShape( gTheBackground );
-
- /***************************************************/
- /* Draw the moving objects in their new positions. */
- /***************************************************/
-
- for (i = 0; i < kMaxObjects; i++)
- {
- GXDrawShape( gMovingObject[i].shape );
-
- GXGetShapeBounds( gMovingObject[i].shape, 0L, &bounds );
-
- xpos = bounds.left;
- ypos = bounds.top;
-
- xdelta = ff( gMovingObject[i].xdelta / 2 );
- ydelta = ff( gMovingObject[i].ydelta / 2 );
-
- /***************************************************/
- /* If the object goes beyond the offscreen bounds, */
- /* make it go in the opposite direction. */
- /***************************************************/
-
- if (xpos + xdelta >= ff( kWinWidth ) || xpos + xdelta <= ff( 0 ))
- gMovingObject[i].xdelta = -gMovingObject[i].xdelta;
-
- if (ypos + ydelta >= ff( kWinHeight ) || ypos + ydelta <= ff( 0 ))
- gMovingObject[i].ydelta = -gMovingObject[i].ydelta;
-
- GXMoveShapeTo( gMovingObject[i].shape, xpos + xdelta, ypos + ydelta );
- }
- }
-
- /*-----------------------------------------------------------------------------------*/
-
- void disposeOffscreen()
- {
- DisposeOffscreen( &gOffscreen );
- }
-
- /*-----------------------------------------------------------------------------------*/
-
- void drawOffscreen()
- {
- GXDrawShape( gOffscreen.draw );
- }
-
- /*-----------------------------------------------------------------------------------*/
-
- void doEventLoop()
- {
- EventRecord event;
- WindowPtr window;
- short clickArea;
- Rect screenRect;
- long ticks = 0;
-
- for (;;)
- {
- /************************************************/
- /* Update the offscreen once every 1/30 second. */
- /************************************************/
-
- if (TickCount() - ticks > 2)
- {
- updateOffscreen();
- drawOffscreen();
- ticks = TickCount();
- }
-
- /***************************/
- /* Handle incoming events. */
- /***************************/
-
- if (WaitNextEvent( everyEvent, &event, 0, nil ))
- {
- if (event.what == mouseDown)
- {
- clickArea = FindWindow( event.where, &window );
-
- if (clickArea == inDrag)
- {
- screenRect = (**GetGrayRgn()).rgnBBox;
- DragWindow( window, event.where, &screenRect );
- }
- else if (clickArea == inContent)
- {
- if (window != FrontWindow())
- SelectWindow( window );
- }
- else if (clickArea == inGoAway)
- if (TrackGoAway( window, event.where ))
- return;
- }
- else if (event.what == updateEvt)
- {
- window = (WindowPtr)event.message;
- SetPort( window );
-
- BeginUpdate( window );
- drawOffscreen();
- EndUpdate( window );
- }
- }
- }
- }
-
- /*-----------------------------------------------------------------------------------*/
-
- int absInteger( num )
- int num;
- {
- int absolute;
-
- absolute = num;
-
- if (absolute < 0)
- absolute = -absolute;
-
- return absolute;
- }
-
- /*-----------------------------------------------------------------------------------*/
-
- int randomInteger( min, max )
- int min, max;
- {
- long randomNum;
-
- randomNum = Random();
-
- if (min >= 0 && max >= 0)
- {
- if (randomNum < 0)
- randomNum = -randomNum;
- }
-
- randomNum = ((randomNum * (max - min)) / 32767) + min;
-
- return randomNum;
- }
-
- /*-----------------------------------------------------------------------------------*/
-
- int randomSignInteger( start, end )
- int start, end;
- {
- long randomNum;
- int sign = 1;
-
- if ((randomNum = Random()) < 0)
- {
- randomNum = -randomNum;
- sign = -1;
- }
-
- randomNum = (((randomNum * (end - start)) / 32767) + start) * sign;
-
- return randomNum;
- }
-
- /*-----------------------------------------------------------------------------------*/
-
- void getRandomColor( r, g, b )
- long *r, *g, *b;
- {
- long randomNum;
- int choice;
-
- randomNum = Random();
- choice = absInteger( (randomNum * 7) / 32767 );
-
- if (choice == 0) /*** red ***/
- {
- *r = 0xffff;
- *g = 0;
- *b = 0;
- }
- else if (choice == 1) /*** green ***/
- {
- *r = 0;
- *g = 0xffff;
- *b = 0;
- }
- else if (choice == 2) /*** blue ***/
- {
- *r = 0;
- *g = 0;
- *b = 0xffff;
- }
- else if (choice == 3) /*** yellow ***/
- {
- *r = 0xffff;
- *g = 0xffff;
- *b = 0;
- }
- else if (choice == 4) /*** magenta ***/
- {
- *r = 0xffff;
- *g = 0;
- *b = 0xffff;
- }
- else if (choice == 5) /*** cyan ***/
- {
- *r = 0;
- *g = 0xffff;
- *b = 0xffff;
- }
- else if (choice == 6) /*** white ***/
- {
- *r = 0xffff;
- *g = 0xffff;
- *b = 0xffff;
- }
- }